/** 
 * XMLMatchReporter.java Created by iweerarathna on Aug 30, 2011.
 * 
 * Copyright (c) 2011 Virtusa Corporation. All Rights Reserved.<br><br>. 
 * 
 */
package org.uim.cricket.analyzer.report;

import java.io.IOException;

import org.uim.cricket.analyzer.parsers.Plogger;
import org.uim.cricket.entities.aggr.SingleInning;
import org.uim.cricket.entities.match.CricketMatch;
import org.uim.cricket.util.io.FileSaver;

/**
 * @version 
 * @author iweerarathna
 */
public class XMLMatchReporter implements MatchReportable {

    private static final String XML_HEADER = "<?xml version=\"1.0\" ?>";
    private String xmlFile = null;
    
    private StringBuilder xml = null;
    
    public XMLMatchReporter() {
        
    }
    
    public XMLMatchReporter(String theXMLFilePath) {
        xmlFile = theXMLFilePath;
    }
    
    @Override
    public boolean reportMatch(CricketMatch match) throws Exception {
        xml = new StringBuilder();
        xml.append(XML_HEADER);
        xml.append("\n");
        
        XMLMatchHeaderReporting hreport = new XMLMatchHeaderReporting();
        xml.append(hreport.getMatchHeaderXMLText(match).toString());
        
        xml.append('\n');
        
        if (match.getInnings() != null) {
            SingleInning[] inns = match.getInnings();
            XMLInningReporting innReporter = new XMLInningReporting(true, true, true);
            for (int i=0;i<inns.length;i++) {
            	if (inns[i] == null) continue;
                StringBuilder sb = innReporter.appendSingleInning(inns[i], 1);
                xml.append(sb.toString());
            }
        } 
        
        xml.append("</CricketMatch>");
        
        if (this.xmlFile != null) {
            Plogger.debug("  Saving to file: " + this.xmlFile);
            FileSaver fs = new FileSaver(this.xmlFile);
            
            try {
                fs.write(xml);
            } catch (IOException e) {
                Plogger.debug("Cann't write to the file " + this.xmlFile);
                Plogger.debug("", e);
            }
            
        }
        
        
        return true;
    }
    
    /*
    private void appendSingleInning(SingleInning inn, int indent) {
        this.appendXMLLineIndent(xml, indent);
        xml.append("<Inning");
        xml.append(this.appendXMLAttrib("id", inn.getInningMatch(), false));
        if (inn.getTargetChased() > 0) {
            xml.append(this.appendXMLAttrib("target", inn.getTargetChased(), false));
            if (inn.getTargetChasedOvers() != null) {
                xml.append(this.appendXMLAttrib("targetOvers", inn.getTargetChasedOvers(), false));
            }
        }
        xml.append(">\n");

        if (inn.getTotals() != null) {
            this.appendXMLLineIndent(xml, indent + 1);
            xml.append("<Total");
            xml.append(this.appendXMLAttrib("runs", inn.getTotals().getRuns(), false));
            xml.append(this.appendXMLAttrib("overs", inn.getTotals().getOvers(), false));
            xml.append(this.appendXMLAttrib("wickets", inn.getTotals().getWickets(), false));
            if (inn.getTotals().getMinutes() > 0) {
                xml.append(this.appendXMLAttrib("mins", inn.getTotals().getMinutes(), false));
            }
            if (inn.getTotals().isDeclared()) {
                xml.append(this.appendXMLAttrib("declared", inn.getTotals().isDeclared(), false));
            }
            xml.append(" />\n");
        }
        if (inn.getExtras() != null) {
            InningExtras extras = inn.getExtras();
            
            this.appendXMLLineIndent(xml, indent + 1);
            xml.append("<Extras");
            if (extras.getBies() > 0) {
                xml.append(this.appendXMLAttrib("bies", extras.getBies(), false));
            }
            if (extras.getLegBies() > 0) {
                xml.append(this.appendXMLAttrib("legbies", extras.getLegBies(), false));
            }
            if (extras.getNoBalls() > 0) {
                xml.append(this.appendXMLAttrib("noballs", extras.getNoBalls(), false));
            }
            if (extras.getWides() > 0) {
                xml.append(this.appendXMLAttrib("wides", extras.getWides(), false));
            }
            if (extras.getPanelties() > 0) {
                xml.append(this.appendXMLAttrib("penalties", extras.getPanelties(), false));
            }
            if (extras.getOthers() > 0) {
                xml.append(this.appendXMLAttrib("others", extras.getOthers(), false));
            }
            xml.append(" />\n");
        }

        this.appendXMLLineIndent(xml, indent + 1);
        xml.append("<Battings");
        xml.append(this.appendXMLAttrib("team", inn.getBattedTeam(), true));
        xml.append(">\n");
        
        List<BattingInning> bats = inn.getBatInnings();
        if (bats != null) {
            
            for (int i = 0; i<bats.size();i++) {
                BattingInning batinn = bats.get(i);
                
                this.appendXMLLineIndent(xml, indent + 2);
                xml.append("<BatInn");
                xml.append(this.appendXMLAttrib("id", (i+1), false)).append(">\n");
                
                this.appendXMLLineIndent(xml, indent + 3);
                xml.append("<Batsman");
                xml.append(this.appendXMLAttrib("id", batinn.getBatsman().getId(), false));
                xml.append(this.appendXMLAttrib("name", batinn.getBatsman().getTitleName(), true));
                xml.append(this.appendXMLAttrib("shortname", batinn.getBatsman().getShortName(), true));
                if (batinn.getBatsman().isCaptain()) {
                    xml.append(this.appendXMLAttrib("captain", batinn.getBatsman().isCaptain(), false));
                }
                if (batinn.getBatsman().isWicketKeeper()) {
                    xml.append(this.appendXMLAttrib("keeper", batinn.getBatsman().isWicketKeeper(), false));
                }
                xml.append(" />\n");
                
                if (batinn.getOutDetails() != null) {
                    this.appendXMLLineIndent(xml, indent + 3);
                    xml.append("<OutDetails");
                    xml.append(this.appendXMLAttrib("type", batinn.getOutDetails().getOutType().toString(), false));
                    if (batinn.getOutDetails().getBowler() != null) {
                        xml.append(this.appendXMLAttrib("bowler", batinn.getOutDetails().getBowler().getTitleName(), true));
                    }
                    if (batinn.getOutDetails().getFielders() != null) {
                        Player[] fielders = batinn.getOutDetails().getFielders();
                        boolean[] wks = batinn.getOutDetails().getWicketKeeperFielders();
                        String fields = "";
                        for (int j=0;j<fielders.length;j++) {
                            if (j>0) fields += ",";
                            if (wks != null && wks[j]) fields += "+";
                            fields += StringEscapeUtils.escapeXml(fielders[j].getTitleName());
                        }
                        xml.append(this.appendXMLAttrib("fielders", fields, false));
                    }
                    xml.append(" />\n");
                }
                
                if (batinn.getStatistics() != null) {
                    this.appendXMLLineIndent(xml, indent + 3);
                    xml.append("<Stats");
                    xml.append(this.appendXMLAttrib("runs", batinn.getStatistics().getRuns(), false));
                    xml.append(this.appendXMLAttrib("balls", batinn.getStatistics().getBalls(), false));
                    xml.append(this.appendXMLAttrib("mins", batinn.getStatistics().getMins(), false));
                    xml.append(this.appendXMLAttrib("fours", batinn.getStatistics().getFours(), false));
                    xml.append(this.appendXMLAttrib("sixes", batinn.getStatistics().getSixes(), false));
                    xml.append(" />\n");
                }
                
                this.appendXMLLineIndent(xml, indent + 2);
                xml.append("</BatInn>\n");
            }
            
        }
        this.appendXMLLineIndent(xml, indent + 1);
        xml.append("</Battings>\n");
        
        this.appendXMLLineIndent(xml, indent + 1);
        xml.append("<Bowlings>\n");
        List<BowlingInning> bowls = inn.getBowlInnings();
        if (bowls != null) {
            
            for (int i=0;i<bowls.size();i++) {
                BowlingInning bowlinn = bowls.get(i);
                
                this.appendXMLLineIndent(xml, indent + 2);
                xml.append("<BowlInn");
                xml.append(this.appendXMLAttrib("id", (i+1), false));
                xml.append(">\n"); 
                
                this.appendXMLLineIndent(xml, indent + 3);
                xml.append("<Bowler");
                xml.append(this.appendXMLAttrib("id", bowlinn.getBowler().getId(), false));
                xml.append(this.appendXMLAttrib("name", bowlinn.getBowler().getTitleName(), true));
                xml.append(this.appendXMLAttrib("shortname", bowlinn.getBowler().getShortName(), true));
                xml.append(" />\n");
                
                this.appendXMLLineIndent(xml, indent + 3);
                xml.append("<Stats");
                xml.append(this.appendXMLAttrib("overs", bowlinn.getStatistics().getOvers(), false));
                xml.append(this.appendXMLAttrib("maidnes", bowlinn.getStatistics().getMaidnes(), false));
                xml.append(this.appendXMLAttrib("runs", bowlinn.getStatistics().getRuns(), false));
                xml.append(this.appendXMLAttrib("wickets", bowlinn.getStatistics().getWickets(), false));
                xml.append(this.appendXMLAttrib("nb", bowlinn.getStatistics().getNoballs(), false));
                xml.append(this.appendXMLAttrib("wd", bowlinn.getStatistics().getWides(), false));
                xml.append(" />\n");
                
                this.appendXMLLineIndent(xml, indent + 2);
                xml.append("</BowlInn>\n");
            }
            
        }
        
        this.appendXMLLineIndent(xml, indent + 1);
        xml.append("</Bowlings>\n");
       
        this.appendXMLLineIndent(xml, indent + 1);
        xml.append("<Wickets>\n");
        
        List<FallOfWicket> fows = inn.getFallWickets();
        if (fows != null) {
            
            for (int i=0;i<fows.size();i++) {
                FallOfWicket fow = fows.get(i);
                
                this.appendXMLLineIndent(xml, indent + 2);
                xml.append("<Wicket");
                xml.append(this.appendXMLAttrib("no", fow.getWicket(), false));
                xml.append(this.appendXMLAttrib("fallruns", fow.getFallOfRuns(), false));
                xml.append(this.appendXMLAttrib("outbatsman", fow.getOutPlayer().getTitleName(), true));
                if (fow.isRetiredHurt()) {
                    xml.append(this.appendXMLAttrib("retired", fow.isRetiredHurt(), false));
                }
                if (fow.getFallOfOver() != null) {
                    xml.append(this.appendXMLAttrib("fallover", fow.getFallOfOver(), false));
                }
                xml.append(" />\n");
                
            }
            
        }
        this.appendXMLLineIndent(xml, indent + 1);
        xml.append("</Wickets>\n");
        
        this.appendXMLLineIndent(xml, indent);
        xml.append("</Inning>\n");
    }
    
    private String appendXMLAttrib(String attrb, boolean value, boolean doencode) {
        return this.appendXMLAttrib(attrb, (value ? "true" : "false"), doencode);
    }
    private String appendXMLAttrib(String attrb, int value, boolean doencode) {
        return this.appendXMLAttrib(attrb, value + "", doencode);
    }
    private String appendXMLAttrib(String attrb, String value, boolean doencode) {
        if (doencode) {
            return " " + attrb + "=\"" + StringEscapeUtils.escapeXml(value) + "\"";
        } else {
            return " " + attrb + "=\"" + (value) + "\"";
        }
    }
    private void appendXMLLineIndent(StringBuilder xml, int indent) {
        for (int i=0;i<indent;i++) {
            xml.append('\t');
        }
    }
    */
    
    public String getXmlFile() {
        return xmlFile;
    }
    
    public void setXmlFile(String xmlFile) {
        this.xmlFile = xmlFile;
    }
    
}
